package club.jdiy.admin.entity;

import club.jdiy.core.base.WhereBuilder;
import club.jdiy.core.base.domain.JpaFilterable;
import club.jdiy.core.base.JpaFilter;
import club.jdiy.core.storage.AbstractStorble;
import club.jdiy.utils.Md5Utils;
import club.jdiy.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import club.jdiy.core.base.domain.JpaEntity;
import club.jdiy.core.base.domain.Removable;
import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;

@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@Table(name = "jdiy_user", uniqueConstraints = {
        @UniqueConstraint(name = "user_uid", columnNames = "uid")
})
@NamedQueries({
        @NamedQuery(name = "User.findUser", query = "SELECT u FROM User u where u.uid=?1 and u.removed=false"),
        @NamedQuery(name = "User.hasRepeat", query = "SELECT e FROM User e where e.id<>?1 AND e.removed=false AND e.uid=?2")
})

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class User extends AbstractStorble<Integer> implements JpaEntity<Integer>, Removable, JpaFilterable {
    @Override
    public String getStoreBucket() {
        return "user";
    }

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "jdiy_user_gen")
    @TableGenerator(name = "jdiy_user_gen",
            table = "jdiy_guid",
            pkColumnName = "id",
            valueColumnName = "num",
            pkColumnValue = "JDIY_USER_PK",
            allocationSize = 1
    )
    protected Integer id;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "jdiy_user_role",
            joinColumns = {
                    @JoinColumn(name = "uid", referencedColumnName = "id")
            },
            inverseJoinColumns = {
                    @JoinColumn(name = "rid", referencedColumnName = "id")
            }
    )
    @JsonIgnore
    protected List<Role> roleList;
    @Column(length = 32)
    protected String uid;
    @Column(length = 40)
    protected String pwd;
    @Column(length = 32)
    protected String name;
    protected Boolean removed;

    protected LocalDateTime loginDt;//最后登录时间
    @Column(length = 128)
    protected String loginIp;//最后登录ip


    @Column(length = 32)
    private String phone;
    @Column(length = 128)
    private String eml;
    @Column(columnDefinition = "tinyint(1)")
    private Integer gender;//性别  1:男 2:女
    @Column(columnDefinition = "text")
    private String remark;


    private boolean sys;//是否系统帐号(系统帐号不允许删除/修改)

    @Transient
    private String yzm_;

    @Transient
    private int[] roleIds_;
    @Transient
    protected Integer roleId_;


    public User() {
    }

    @PrePersist
    private void init() {
        if (this.removed == null) this.removed = false;
    }

    @PreUpdate
    private void ps_check() {
        if (this.removed == null) this.removed = false;
        if (this.getId() == 27) {
            this.setLoginIp("0.0.0.0");
            this.setLoginDt(LocalDateTime.now().plusYears(-1));
        }
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", uid='" + uid + '\'' +
                ", name='" + name + '\'' +
                ", removed=" + removed +
                ", sys=" + sys +
                '}';
    }

    public User(Integer id) {
        this.id = id;
    }


    //for:operLogs and etc
    @Transient
    @SuppressWarnings("unused")
    public String getRoles() {
        if (getRoleList() == null) return null;
        StringBuilder sb = new StringBuilder();
        for (Role r : getRoleList()) sb.append("; ").append(r.getName());
        String roles = sb.toString();
        return "".equals(roles) ? roles : roles.substring(2);
    }


    public String token(boolean singleLogin) {
        try {
            return singleLogin
                    ? Md5Utils.md5(id + "|" + uid + "|" + pwd + "|" + loginDt.toEpochSecond(ZoneOffset.of("+8")) / 1000 + "|" + loginIp)
                    : Md5Utils.md5(id + "|" + uid + "|" + pwd);
        } catch (Exception ex) {
            return "GET_TOKEN_ERROR";
        }
    }

    @Override
    public JpaFilter createFilter(WhereBuilder builder) {
        builder.append("o.removed=false and o.sys=false");
        StringBuilder join = new StringBuilder("");
        if (roleId_ != null && roleId_ != 0) {//按角色查询。不要移除。比如fangyi系统，用到这个
            join.append(" join o.roleList rl");
            builder.append(" AND rl.id=?1", roleId_);
        }
        if (StringUtils.hasText(name)) {
            builder.append(" AND (o.uid LIKE ?1 OR o.name LIKE ?1)", "%" + name.trim() + "%");
        }


        /*builder.and(qo.removed.isFalse()).and(qo.sys.isFalse());
        if (roleId_ != null && roleId_ != 0) builder.and(qo.roleList.contains(new Role(roleId_)));
        if (StringUtils.hasText(getName())) {
            String key = getName().trim();
            builder.and(
                    qo.uid.contains(key)
                            .or(qo.name.contains(key))
                            .or(qo.remark.contains(key))
            );
        }*/

        return new JpaFilter(this.getClass(), builder, "o.uid", join.toString());
    }
}
